﻿/*****************************************************************//**
 * \file   CProimse.h
 * \brief  CProimse类是一个Promise的实现，用于处理异步操作。
 *         它支持三种状态：PENDING、FULFILLED和REJECTED。
 *
 * \author 郝学胜
 * \date   2025-09-20
 *********************************************************************/

#pragma once

#include <list>
#include <string>
#include <functional>

namespace Softwarer {

    /**
     * \brief CProimseState枚举表示Promise的状态。
     * \details 包括三种状态：PENDING（进行中）、FULFILLED（已成功）、REJECTED（已拒绝）。
     */
    enum CProimseState
    {
        PENDING,    /**< 状态：进行中 */
        FULFILLED,  /**< 状态：已成功 */
        REJECTED    /**< 状态：已拒绝 */
    };

    /**
     * \brief CProimse类是一个Promise的实现，用于处理异步操作。
     * \details 该类支持异步操作的完成、拒绝以及注册回调函数。
     * \tparam Element 异步操作的结果类型。
     */
    template<typename Element>
    class CProimse
    {
    private:
        /**
         * \brief 定义Resolve类型，表示成功回调函数。
         * \details 成功回调函数接受一个Element类型的参数。
         */
        using Resolve = std::function<void(Element)>;

        /**
         * \brief 定义Reject类型，表示失败回调函数。
         * \details 失败回调函数接受一个const std::string&类型的参数。
         */
        using Reject = std::function<void(const std::string&)>;

    private:
        Element m_element;      /**< 异步操作的结果 */
        std::string m_reason;   /**< 拒绝的原因 */
        CProimseState m_state;  /**< 当前状态 */
        std::list<Resolve> m_resolves; /**< 成功回调函数列表 */
        std::list<Reject> m_rejects;   /**< 失败回调函数列表 */

    public:
        /**
         * \brief CProimse类的构造函数。
         * \details 初始化状态为PENDING。
         */
        CProimse()
            : m_state(CProimseState::PENDING)
        {
        }

        /**
         * \brief 拒绝Promise的方法。
         * \details 将状态设为REJECTED，并调用所有注册的失败回调函数。
         * \param reason 拒绝的原因。
         */
        void reject(const std::string& reason)
        {
            m_reason = reason;
            if (m_state == CProimseState::PENDING)
            {
                m_state = CProimseState::REJECTED;
                for (Reject rej : m_rejects)
                {
                    rej(reason);
                }
            }
        }

        /**
         * \brief 完成Promise的方法。
         * \details 将状态设为FULFILLED，并调用所有注册的成功回调函数。
         * \param element 完成的结果。
         */
        void resolve(Element element)
        {
            m_element = element;
            if (m_state == CProimseState::PENDING)
            {
                m_state = CProimseState::FULFILLED;
                for (Resolve res : m_resolves)
                {
                    res(element);
                }
            }
        }

        /**
         * \brief 注册错误处理回调函数的方法。
         * \details 如果Promise已经拒绝，则立即调用回调函数；否则，将回调函数添加到失败回调列表中。
         * \param rej 失败回调函数。
         */
        void onCatch(const Reject& rej)
        {
            if (m_state == CProimseState::REJECTED)
            {
                rej(m_reason);
            }
            else if (m_state == CProimseState::PENDING)
            {
                m_rejects.push_back(rej);
            }
        }

        /**
         * \brief 注册成功处理回调函数的方法。
         * \details 如果Promise已经完成，则立即调用回调函数；否则，将回调函数添加到成功回调列表中。
         * \param res 成功回调函数。
         * \return 返回当前的CProimse对象，支持链式调用。
         */
        CProimse* then(const Resolve& res)
        {
            if (m_state == CProimseState::FULFILLED)
            {
                res(m_element);
            }
            else if (m_state == CProimseState::PENDING)
            {
                m_resolves.push_back(res);
            }
            return this;
        }
    };

}